package com.zjl.SpringBoot.第07章_核心部分;

import com.zjl.util.OutColour;
import org.springframework.boot.*;
import org.springframework.boot.availability.AvailabilityChangeEvent;
import org.springframework.boot.availability.LivenessState;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.event.*;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;

/**
 * 各种回调监听器
 * {@link BootstrapRegistryInitializer}：感知引导初始化【感知特定阶段】
 *          可以在 META-INF/spring.factories 配置，也可以调用 {@link SpringApplication}.addBootstrapRegistryInitializer()
 *          创建引导上下文bootstrapContext的时候触发 几乎最早使用
 *          场景：进行密钥校对授权
 * {@link ApplicationContextInitializer}： 感知ioc容器初始化【感知特定阶段】
 *      可以在META-INF/spring.factories 配置，也可以调用  {@link SpringApplication}.addInitializers()
 * {@link ApplicationListener}：基于事件机制感知事件，具体的阶段可以做别的事 【感知全阶段的事件】
 *      可以在META-INF/spring.factories 配置，
 *          也可以调用 {@link SpringApplication}.addListeners(…)或 {@link SpringApplicationBuilder}.listeners(…)
 *      也可以通过 {@link Bean} 或 {@link EventListener} 基于事件触发  注入IOC容器
 *      不仅能感知生命周期的事件，还可以感知运行时发生的事件，可以实现基于事件驱动模式的应用开发
 * {@link SpringApplicationRunListener}：各种阶段都能自定义操作，功能比ApplicationListener更完善【感知全阶段生命周期且可操作】
 *      需要在META-INF/spring.factories配置
 * {@link ApplicationRunner}：感知应用就绪Ready，应用卡死就不会就绪【感知特定阶段】
 *      只要是容器中的组件就可以被获取到，可以使用【不限于】@Bean注入容器
 *           @Bean
 *           public ApplicationRunner applicationRunner(){
 *               return args -> {
 *                   System.out.println("ApplicationRunner运行了，参数为"+args);
 *               };
 *           }
 *
 * {@link CommandLineRunner}：感知应用就绪Ready，应用卡死就不会就绪【感知特定阶段】
 *
 * *****************************************************************************************************
 * 事件完整触发流程【九大事件】
 * {@link ApplicationStartingEvent}：应用启动但未做任何事情,，除了注册listeners and initializers
 * {@link ApplicationEnvironmentPreparedEvent}：Environment 准备好，但context 未创建
 * {@link ApplicationContextInitializedEvent}：ApplicationContext准备好，ApplicationContextInitializers调用，但是任何bean未加载
 * {@link ApplicationPreparedEvent}：容器刷新之前，bean定义信息加载
 * {@link ApplicationStartedEvent}：容器刷新完成， runner未调用
 *    ========以下就开始插入了探针机制，对接云上平台====
 * {@link AvailabilityChangeEvent }：{@link LivenessState.CORRECT}应用存活【存活探针】
 * {@link ApplicationReadyEvent}：任何runner被调用
 * {@link AvailabilityChangeEvent}：ReadinessState.ACCEPTING_TRAFFIC【就绪探针】，可以接请求
 * {@link ApplicationFailedEvent }：启动出错
 * 
 * 
 */
public class B_事件触发时机 {
    public static void main(String[] args) {
        SpringApplication springApplication = new SpringApplication(B_事件触发时机.class);



//        springApplication.run(args);//运行
        springApplication.run("args");//运行

    }



}
@Component
class MyApplicationRunner implements ApplicationRunner{

    @Override
    public void run(ApplicationArguments args) throws Exception {
        OutColour.out.printlnGreen("============ApplicationRunner============");
    }

}
@Component
class MyCommandLineRunner implements CommandLineRunner{

    @Override
    public void run(String... args) throws Exception {
        OutColour.out.printlnGreen("============CommandLineRunner============",args);

    }
}